package logistics

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	redis2 "gitee.com/dsler-go/utils/servers/redis"
	"io/ioutil"
	"net/http"
	"time"
)

const (
	AliLogisticsCachePre = "logistics:ali_"
	AliLogisticHost      = "https://wuliu.market.alicloudapi.com/kdi"
)

// AliLogisticsResponse 阿里物流接口返回
type AliLogisticsResponse struct {
	Status string       `json:"status"`
	Msg    string       `json:"msg"`
	Result ResultDetail `json:"result"`
}

type ResultDetail struct {
	Number         string       `json:"number"`
	Type           string       `json:"type"`
	TypeName       string       `json:"typename"`
	Logo           string       `json:"logo"`
	List           []ListDetail `json:"list"`
	Deliverystatus string       `json:"deliverystatus"`
	Issign         string       `json:"issign"`
}

type ListDetail struct {
	Time   string `json:"time"`
	Status string `json:"status"`
}

type AliLogistics struct {
	appCode string
	ts      int
}

var DefaultAliLogisticsClient = &AliLogistics{}

func InitAliLogistics(appCode string, ts int) {
	DefaultAliLogisticsClient.appCode = appCode
	DefaultAliLogisticsClient.ts = ts
}

// GetLogisticsByAli 请求阿里物流接口
func (c *AliLogistics) GetLogisticsByAli(number, companyCode string) (*AliLogisticsResponse, error) {
	url := fmt.Sprintf("%v?no=%v&type=%v", AliLogisticHost, number, companyCode)
	respBytes, err := c.sendGetRequest(url)
	if err != nil {
		return nil, err
	}
	var res1 *AliLogisticsResponse
	err = json.Unmarshal(respBytes, &res1)
	if err != nil {
		return nil, errors.New(LogisticNotExist)
	}
	cacheKey := AliLogisticsCachePre + number
	if res1.Status != "0" {
		_ = redis2.DefaultRedisV8.Client.Set(context.Background(), cacheKey, respBytes, time.Hour)
		return nil, errors.New(LogisticNotExist)
	} else {
		cacheTime := time.Duration(DefaultAliLogisticsClient.ts) * time.Hour // 其他状态的物流   缓存2小时
		if res1.Result.Deliverystatus == "3" {
			cacheTime = 24 * 90 * time.Hour // 已签收订单  缓存redis90天
		}
		_ = redis2.DefaultRedisV8.Client.Set(context.Background(), cacheKey, respBytes, cacheTime)
		return res1, nil
	}
}

func (c *AliLogistics) sendGetRequest(url string) ([]byte, error) {
	client := &http.Client{}
	reqest, err := http.NewRequest("GET", url, nil) //建立一个请求
	if err != nil {
		return nil, err
	}
	reqest.Header.Add("Authorization", fmt.Sprintf("APPCODE %v", c.appCode))
	reqest.Header.Add("Content-Type", "application/json; charset=UTF-8")
	resp, err := client.Do(reqest) //提交
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	respBytes, err := ioutil.ReadAll(resp.Body)
	return respBytes, nil
}
